/**
 *  检测字符串真正显示在屏幕上时占了多少格
 *  例:
 *      [...'\t'ljh]
 *      [<---7---->]
 */
#pragma once
#include <string>
#include <stdexcept>
using namespace std;
class ZiFuScreenZhanWeiJiSuan {
public:static void append_wide_char_simple(std::string& str, wchar_t wc) {
        // 设置 locale（假设使用系统默认）
        static bool locale_set = false;
        if (!locale_set) {
            std::setlocale(LC_ALL, "");
            locale_set = true;
        }

        // 转换宽字符
        char mb_str[MB_CUR_MAX] = {0};
        std::wctomb(mb_str, wc);

        // 添加到字符串
        str += mb_str;
    }
    // 判断字符是否为宽字符（汉字或全角字符）
    static bool is_wide_character(wchar_t wc) {
        // 基本汉字区 (4E00-9FFF)
        if (wc >= 0x4E00 && wc <= 0x9FFF)
            return true;

        // 扩展汉字区 (3400-4DBF)
        if (wc >= 0x3400 && wc <= 0x4DBF)
            return true;

        // 全角字符区 (FF00-FFEF)
        if (wc >= 0xFF00 && wc <= 0xFFEF)
            return true;

        // CJK符号和标点 (3000-303F)
        if (wc >= 0x3000 && wc <= 0x303F)
            return true;

        // 表情符号区域
        // 杂项符号和象形文字 (1F300-1F5FF)
        if (wc >= 0x1F300 && wc <= 0x1F5FF)
            return true;

        // 补充符号和象形文字 (1F900-1F9FF)
        if (wc >= 0x1F900 && wc <= 0x1F9FF)
            return true;

        // 表情符号 (1F600-1F64F)
        if (wc >= 0x1F600 && wc <= 0x1F64F)
            return true;

        // 运输和地图符号 (1F680-1F6FF)
        if (wc >= 0x1F680 && wc <= 0x1F6FF)
            return true;

        // 杂项符号 (2600-26FF) - 包含一些经典的表情符号如☺☹等
        if (wc >= 0x2600 && wc <= 0x26FF)
            return true;

        // 装饰符号 (2700-27BF) - 包含一些装饰性符号
        if (wc >= 0x2700 && wc <= 0x27BF)
            return true;

        // 补充箭头-C (1F800-1F8FF)
        if (wc >= 0x1F800 && wc <= 0x1F8FF)
            return true;

        // 符号和象形文字扩展-A (1FA70-1FAFF)
        if (wc >= 0x1FA70 && wc <= 0x1FAFF)
            return true;

        return false;
    }

    // 统计UTF-8字符串的显示宽度
    static size_t count_display_width_utf8(const std::string& str) {
        if (str.empty()) return 0;

        // 设置UTF-8 locale
        std::setlocale(LC_ALL, "en_US.UTF-8");

        size_t display_width = 0;
        const char* move_ptr = str.c_str();
        const char* end = move_ptr + str.size();

        while (move_ptr < end) {
            wchar_t wc = L'\0';
            int bytes = std::mbtowc(&wc, move_ptr, str.size());

            if (bytes <= 0) {
                // 无效序列，跳过1字节
                move_ptr++;
                continue;
            }

            // ASCII字符
            if (bytes == 1) {
                if (wc == '\t')
                {
                    switch ((display_width + 1) % 4)
                    {
                    case 1:
                        display_width += 4;
                        break;
                    case 2:
                        display_width += 3;
                        break;
                    case 3:
                        display_width += 2;
                        break;
                    case 0:
                        display_width += 1;
                        break;
                    default:
                        throw logic_error("制表符占位计算逻辑错误!");
                    }
                } else display_width += 1;
            }
            // 宽字符（汉字或全角字符）
            else if (is_wide_character(wc)) {
                display_width += 2;
            }
            // 其他多字节字符
            else {
                display_width += 1;
            }

            move_ptr += bytes;
        }

        return display_width;
    }

    // 统计GBK字符串的显示宽度
    static size_t count_display_width_gbk(const std::string& str) {
        size_t display_width = 0;
        const unsigned char* ptr = reinterpret_cast<const unsigned char*>(str.c_str());
        size_t len = str.size();

        for (size_t i = 0, base_i = 0; i < len; ) {
            // ASCII字符
            if (ptr[i] < 0x80) {
                if (ptr[i] == '\t')
                {
                    switch ((display_width + 1) % 4)
                    {
                    case 1:
                        display_width += 4;
                        break;
                    case 2:
                        display_width += 3;
                        break;
                    case 3:
                        display_width += 2;
                        break;
                    case 0:
                        display_width += 1;
                        break;
                    default:
                        throw logic_error("制表符占位计算逻辑错误!");
                    }
                } else display_width += 1;
                i++;
            }
            // GBK汉字（首字节在0x81-0xFE之间）
            else if (ptr[i] >= 0x81 && ptr[i] <= 0xFE) {
                // 确保有2字节
                if (i + 1 < len) {
                    display_width += 2;
                    i += 2;
                } else {
                    // 不完整的GBK序列
                    display_width += 1;
                    i++;
                }
            }
            // 无效GBK字节
            else {
                display_width += 1;
                i++;
            }
        }

        return display_width;
    }
public:
    // 自动检测编码并统计显示宽度
    static size_t count_display_width(const std::string& str) {
        // 简单启发式检测UTF-8编码
        bool likely_utf8 = true;
        const unsigned char* ptr = reinterpret_cast<const unsigned char*>(str.c_str());
        size_t len = str.size();

        for (size_t i = 0; i < len; ) {
            if (ptr[i] < 0x80) {
                // ASCII字符
                i++;
            } else if ((ptr[i] & 0xE0) == 0xC0) {
                // 2字节UTF-8序列
                if (i + 1 >= len || (ptr[i + 1] & 0xC0) != 0x80) {
                    likely_utf8 = false;
                    break;
                }
                i += 2;
            } else if ((ptr[i] & 0xF0) == 0xE0) {
                // 3字节UTF-8序列
                if (i + 2 >= len || (ptr[i + 1] & 0xC0) != 0x80 || (ptr[i + 2] & 0xC0) != 0x80) {
                    likely_utf8 = false;
                    break;
                }
                i += 3;
            } else if ((ptr[i] & 0xF8) == 0xF0) {
                // 4字节UTF-8序列
                if (i + 3 >= len || (ptr[i + 1] & 0xC0) != 0x80 ||
                    (ptr[i + 2] & 0xC0) != 0x80 || (ptr[i + 3] & 0xC0) != 0x80) {
                    likely_utf8 = false;
                    break;
                }
                i += 4;
            } else {
                // 无效UTF-8序列
                likely_utf8 = false;
                break;
            }
        }

        if (likely_utf8) {
            return count_display_width_utf8(str);
        } else {
            return count_display_width_gbk(str);
        }
    }
};